using System;
using System.ServiceModel.Channels;
using System.Xml;

namespace Albatross.WCF.Extenions.ServiceModel.Channels
{
    internal class CompressionMessageHeader : MessageHeader
    {
        private readonly CompressionAlgorithm _algorithm;
        private readonly CompressionLevel _level;

        public CompressionMessageHeader(CompressionAlgorithm algorithm, CompressionLevel level)
        {
            _algorithm = algorithm;
            _level = level;
        }

        public override string Name
        {
            get { return WSCompressionStrings.Compression; }
        }

        public override bool MustUnderstand
        {
            get { return true; }
        }

        public override string Namespace
        {
            get { return WSCompressionStrings.NamespaceUri; }
        }

        public CompressionAlgorithm Algorithm
        {
            get { return _algorithm; }
        }

        public CompressionLevel Level
        {
            get { return _level; }
        }

        protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
        {
            writer.WriteAttributeString(WSCompressionStrings.Algorithm, WSCompression.Algorithm.ConvertToString(Algorithm));
            writer.WriteAttributeString(WSCompressionStrings.Level, WSCompression.Level.ConvertToString(Level));
        }

        public static CompressionMessageHeader ReadFrom(XmlReader reader)
        {
            if (reader.LocalName != WSCompressionStrings.Compression ||
                reader.NamespaceURI != WSCompressionStrings.NamespaceUri)
                throw new NotSupportedException("Unable to find Compression header element.");

            string algorithm = reader.GetAttribute(WSCompressionStrings.Algorithm);
            string level = reader.GetAttribute(WSCompressionStrings.Level);

            if (String.IsNullOrEmpty(algorithm))
                throw new InvalidOperationException("Unable to resolve algoritm type from header.");
            if (String.IsNullOrEmpty(level))
                throw new InvalidOperationException("Unable to resolve level from header.");

            return new CompressionMessageHeader(WSCompression.Algorithm.ConvertToAlgorithm(algorithm), WSCompression.Level.ConvertToLevel(level));
        }
    }
}